#pragma once
#include "StateMachineState.h"
#include "IUpdateable.hpp"
#include <list>

namespace rh
{
	template <class T, class Enum>
	class StateMachine : public rh::IUpdateable
	{
	private:
		typedef void (T::*VoidFncPtr) (void);
		typedef Enum (T::*CleanupFncPtr)(void);
		typedef void (T::*UpdateFncPtr) (const sf::Time&, const sf::Time&);
		typedef StateMachineState<T, Enum> StateClass;

	private:
		std::list<StateMachineState<T, Enum>> _states;
		StateClass* _currentState;

		bool _isFinished;

	public:
		StateMachine(void)
		{

		};
		~StateMachine(void)
		{
		};

		void AddState(StateClass& state)
		{
			_states.push_back(state);
			if(_states.size() == 1)
				_currentState = &state;
		};

		void AddState(T* target,Enum currentState, VoidFncPtr initializationPtr, UpdateFncPtr updatePtr, CleanupFncPtr cleanupPtr)
		{
			_states.push_back(StateMachineState<T, Enum>(target, currentState, initializationPtr, updatePtr));
		}

		void RemoveState(Enum pos)
		{
			_states.erase(pos);
		};

		virtual void Update(const sf::Time& elapsedTime, const sf::Time& totalElapsedTIme)
		{
			_currentState->Update(elapsedTime, totalElapsedTIme);
		};

		Enum GetCurrentStatePosition(void)
		{
			return _currentState->GetState();
		};
	};
}